#include <stdio.h>
#include <string.h>  //
#include <stdbool.h> // 引入bool类型

#define SIZE 5

struct Person {
    char name[20];  // 姓名
    int age;        // 年龄
    float height;   // 身高
};

typedef struct car{
    char name[20];  // 名称
    float  wight;     // 宽高
    float height;
    char colorChr[20];  //颜色
}CAR;

void printCar(CAR C1) {
    printf("品牌: %s\n", C1.name);
    printf("颜色: %s\n", C1.colorChr);
    printf("高: %.2f\n", C1.height);
    printf("宽: %.2f\n", C1.height);
}

union Data {
    int i;
    float f;
};

// 申明定义函数add
int add(int a, int b) {
    return a + b;
}

void addOutput(int n, int m, int *sum)
{
    *sum = n+m;
    n+=5;
    m+=10;
    if((*sum) < 400)
    {
        addOutput(n,m,sum); // 递归调用
    }
}

int main()
{
    if(1)
    {
        // 数组
        int a[10];
        for(int i = 0; i < 10; ++i)
        {
            a[i] = i*10;
        }

        printf("arr a size : %d\n", sizeof(a));// 获取数组所占字符数
        int  b[SIZE];
        for(int j = 0; j < SIZE ; j++)
        {
            b[j] = a[j] / 2;
        }

        float fArr[] = {3.4, 4.5, 6.6};

        int num[2][4];

        int nn[][2] = {1,2,3,4,21,22,23,24}; // 多维数组初始化后可以不指定，第一维大小

        // 数组在使用时，千万不能越界。
    }

    if(1)
    {   // 指针
        int num = 10;
        int *p;                // 指针的定义
        p = &num;              // '&'这个符号时取地址，将地址值付给指针P
        printf("%d\n", *p);    // '*'这个符号表示取值，表示将P这个地址下的值取出来。
        printf("pointer size:%d\n", sizeof(p));     // 获取指针大小，32位系统，就是4个字节，64位系统，就是8个字节；
        printf("pointer = %p\n", p);//%p表示按照16进制的形式输出指针地址。

        int data[4] ={3,4,5,6};
        int *pNum = data;           // 数组名为指针，数组名是指针常量，不能改变。
        pNum++;
        printf("pNum -> value: %d\n", *pNum);   // 指针 ++，表示指针所直指向的内存地址，增加了一个int型数据的间隔。所以这里输出 4

        int *pData = &data[3];  // 将数组的第四个数据地址赋值给pData;

        pData -= 1;

        printf("pData -> value: %d\n", *pData);   // 指针-1，表示指针所直指向的内存地址，减少了一个int型数据的间隔。所以这里输出 5

        // 指针在进行加减时，要注意不要访问越界。
        int **ppData = &pData;
        printf("ppData -> value: %d\n", **ppData);   // 多级指针。

    }

    if(1)
    {
        // 函数
        int result = add(3, 5);
        printf("两数之和是: %d\n", result);

        int sum = 0, k = 66;
        addOutput(result, k, &sum);    // 这里的sum是出参， result/k,为入参 返回值为void
        printf("sum: %d, k = %d, result=%d \n", sum, k, result);

        int (*pAdd)(int, int);  // 函数指针
        pAdd = add;
        int ret = pAdd(39,45);
        printf("ret: %d\n", ret);
    }

    if(1)
    {
        // 结构体
        struct Person p1;

        // 给结构体变量的成员赋值
        strcpy(p1.name, "张三");
        p1.age = 20;
        p1.height = 1.75;
    
        // 输出结构体变量的成员值
        printf("姓名: %s\n", p1.name);
        printf("年龄: %d\n", p1.age);
        printf("身高: %.2f\n", p1.height);

        CAR C1;
        
        strcpy(C1.name, "奔驰");
        strcpy(C1.colorChr, "red");
        C1.height = 1.7;
        C1.wight = 2.2;
        printCar(C1);
    }

    if(1)
    {
        // 共用体
        // 定义一个共用体变量
        union Data d;

        // 给共用体变量的整数成员赋值
        d.i = 10;
        printf("整数的值: %d\n", d.i);

        // 给共用体变量的浮点数成员赋值
        d.f = 3.14;
        printf("浮点数的值: %.2f\n", d.f);

        printf("整数的值: %d\n", d.i);// 这里整型数据已经被覆盖
    }
    return 0;
}
